package com.ihr360.insurance.service.impl;

import com.google.common.collect.Lists;
import com.ihr360.authority.sharing.annonation.AccessControl;
import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.commons.model.type.BenefitCategory;
import com.ihr360.event.annonation.RestEventHandler;
import com.ihr360.insurance.dao.MandatoryBenefitsTypeReposity;
import com.ihr360.insurance.eventhandler.MandatoryBenefitsTypeRestEventListener;
import com.ihr360.insurance.model.dto.benefits.MandatoryBenefitsType;
import com.ihr360.insurance.model.vo.BenefitTypeVo;
import com.ihr360.insurance.service.MandatoryBenefitsTypeService;
import com.ihr360.rest.reposity.SimpleRestReposity;
import com.ihr360.rest.service.AbstractSimpleRestServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @author david.wei
 */
@Service
@RestEventHandler(MandatoryBenefitsTypeRestEventListener.class)
@AccessControl(disableAll = true)
public class MandatoryBenefitsTypeServiceImpl extends AbstractSimpleRestServiceImpl<MandatoryBenefitsType, Long> implements MandatoryBenefitsTypeService {
    @Autowired
    MandatoryBenefitsTypeReposity reposity;

    @Override
    public SimpleRestReposity<MandatoryBenefitsType, Long> getSimpleRestReposity() {
        return reposity;
    }

    @Override
    public List<BenefitTypeVo> getEnabledTypes() {
        List<MandatoryBenefitsType> allTypes = reposity.getAllByEnabled(true);
        if (CollectionUtils.isEmpty(allTypes)) {
            return Collections.emptyList();
        }
        List<BenefitTypeVo> result = Lists.newArrayList();
        allTypes.forEach(type -> result.add(new BenefitTypeVo(type.getId(), type.getCode(),
                type.getName(), type.getCategory(), type.getEffectiveAt(),
                type.getInvalidAt(), type.isEnabled())));
        return result;
    }

    @Override
    public List<BenefitTypeVo> getCurrentEnabledTypes(Date yearMonthDate, BenefitCategory category) {
        List<MandatoryBenefitsType> allTypes = reposity.getAllByEnabledAndCategoryAndEffectiveAtLessThanEqual(
                true, category, yearMonthDate);
        if (CollectionUtils.isEmpty(allTypes)) {
            return Collections.emptyList();
        }
        return getBenefitTypeVos(yearMonthDate, allTypes);
    }

    @Override
    public List<BenefitTypeVo> getCurrentEnabledTypes(Date yearMonthDate) {
        List<MandatoryBenefitsType> allTypes = reposity.getAllByEnabledAndEffectiveAtLessThanEqual(true, yearMonthDate);
        if (CollectionUtils.isEmpty(allTypes)) {
            return Collections.emptyList();
        }
        return getBenefitTypeVos(yearMonthDate, allTypes);
    }

    @Override
    public List<BenefitTypeVo> getCurrentEnabledTypesIn(List<Long> ids, Date yearMonthDate) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        List<MandatoryBenefitsType> allTypesIn = reposity.getAllByEnabledAndEffectiveAtLessThanEqualAndIdIn(true, yearMonthDate, ids);
        if (CollectionUtils.isEmpty(allTypesIn)) {
            return Collections.emptyList();
        }
        return getBenefitTypeVos(yearMonthDate, allTypesIn);
    }

    private List<BenefitTypeVo> getBenefitTypeVos(Date yearMonthDate, List<MandatoryBenefitsType> allTypesIn) {
        List<BenefitTypeVo> result = Lists.newArrayList();
        allTypesIn.forEach(type -> {
            Date invalidAt = type.getInvalidAt();
            if (invalidAt != null && !invalidAt.after(yearMonthDate)) {
                return;
            }
            BenefitTypeVo vo = new BenefitTypeVo(type.getId(), type.getCode(),
                    type.getName(), type.getCategory(), type.getEffectiveAt(),
                    type.getInvalidAt(), type.isEnabled());
            result.add(vo);
        });
        return result;
    }

    @Override
    public boolean isTypeNameExisted(String name) {
        return reposity.countByName(name) > 0;
    }
}
